package xyz.labmem.main.tool;

import com.alibaba.druid.util.HexBin;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.Data;
import xyz.labmem.main.error.FuncException;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt工具类
 * Created by Lty
 * Created in 11:32 2020-3-4
 */
@Data
public class JWT {

    //默认加密方式
    public static final Key keys = Keys.secretKeyFor(SignatureAlgorithm.HS512);

    //随机密钥
    public static Map<String, String> autoKey = new HashMap<>();

    //默认过期时间秒
    private static long expire = 10000;

    /**
     * 生成jwt key
     *
     * @param value 值
     * @return jwt
     */
    public static String make(String value) {
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(value)
                .signWith(keys)
                .compact();

    }

    /**
     * 生成jwt key
     * 设过期时间
     *
     * @param value 值
     * @return jwt
     */
    public static String makeExpire(String value, Date nowDate, long nexpire) {
        Date expireDate = new Date(nowDate.getTime() + nexpire * 1000);
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(value)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(keys)
                .compact();
    }

    /**
     * 生成jwt key
     * 有过期时间
     *
     * @param value 值
     * @return jwt
     */
    public static String makeExpire(String value, Date nowDate) {
        return makeExpire(value, nowDate, expire);
    }


    /**
     * 验证jwt
     *
     * @param key   key 密钥
     * @param value 原值
     * @return boolean
     */
    public static boolean verify(String key, String value) {
        return getValue(key).equals(value);
    }

    /**
     * 验证jwt
     *
     * @param key   key 密钥
     * @param value 原值
     * @return boolean
     */
    public static boolean verifyExpire(String key, String value) {
        try {
            return Jwts.parser()
                    .setSigningKey(keys)
                    .parseClaimsJws(key)
                    .getBody()
                    .getSubject()
                    .equals(value);
        } catch (Exception e) {
            new FuncException("验证jwt错误", e);
            return false;
        }
    }

    /**
     * 获取jwt的值
     *
     * @param key 密钥
     * @return 解值
     */
    public static String getValue(String key) {
        try {
            return Jwts.parser()
                    .setSigningKey(keys)
                    .parseClaimsJws(key)
                    .getBody()
                    .getSubject();
        } catch (Exception e) {
            new FuncException("获取jwt错误", e);
            return null;
        }
    }

    /**
     * 随机密钥生成jwt HS512 key
     * 设过期时间
     *
     * @param value 值
     * @return jwt
     */
    public static String makeExpireByAutoKey(String value, Date nowDate, long nexpire) {
        Key keys = Keys.secretKeyFor(SignatureAlgorithm.HS512);
        Date expireDate = new Date(nowDate.getTime() + nexpire * 1000);
        String token = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(value)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(keys)
                .compact();
        autoKey.put(token, HexBin.encode(keys.getEncoded()));
        return token;
    }


    /**
     * 通过对应的key获取jwt的值
     *
     * @param key 密钥
     * @return 解值
     */
    public static String getValueByKeyStr(String key, String keyStr) {
        try {
            //转换密钥
            return Jwts.parser()
                    .setSigningKey(Keys.hmacShaKeyFor(HexBin.decode(keyStr)))
                    .parseClaimsJws(key)
                    .getBody()
                    .getSubject();
        } catch (Exception e) {
            new FuncException("获取jwt错误", e);
            return null;
        }
    }

}
